<?php
/**
 * Created by PhpStorm.
 * Author: sitenv@aliyun.com
 * CreateTime: 2021/07/15 20:07
 * Blog：www.myblogs.xyz
 */

namespace app\admin\controller;


use app\common\model\MemberBalance;
use app\common\model\MemberFinance;
use think\facade\View;

class Order extends Common
{
    public function index()
    {
        $param = input('param.');
        $status = input('param.status');
        $is_overtime = input('param.is_overtime', 0, 'intval');
        $is_account = input('param.is_account', 0, 'intval');
        $time_range = input('param.time_range', 0, 'intval');
        $keywords = input('param.keywords');
        // The query time
        $list_where = [];
        $start_time = empty($param['start_time']) ? '' : $param['start_time'];
        $end_time = empty($param['end_time']) ? '' : $param['end_time'];
        if (!empty($start_time)){
            if (strtotime($start_time)){
                $beg = strtotime($start_time . ' 00:00:00');
                if (!empty($end_time) && strtotime($end_time)){
                    $end = strtotime($end_time . ' 23:59:59');
                }else{
                    $date = date('Y-m-d',NEW_TIME) . ' 23:59:59';
                    $end = strtotime($date);
                }
                $list_where[] = ['start_time', 'between', [$beg, $end]];
            }
        }else{
            if (empty($keywords)){
                if ($time_range < 5){
                    $date = date('Y-m-d',NEW_TIME) . ' 23:59:59';
                    $end = strtotime($date);
                    if ($time_range == 4){
                        $beg = strtotime($date . ' -12 month');
                    }elseif ($time_range == 3){
                        $beg = strtotime($date . ' -6 month');
                    }elseif ($time_range == 2){
                        $beg = strtotime($date . ' -3 month');
                    }elseif ($time_range == 1){
                        $beg = strtotime($date . ' -1 month');
                    }else{
                        $beg = strtotime($date . ' -15 day');
                    }
                    $list_where[] = ['start_time', 'between', [$beg, $end]];
                }
            }
        }
        // keywords
        if (!empty($keywords)){
            if (strlen($keywords) > 16){
                $list_where[] = ['order_code', '=', $keywords];
            }else{
                if (is_mobile($keywords)){
                    $list_where[] = ['mobile', '=', $keywords];
                }else{
                    $list_where[] = ['number', '=', $keywords];
                }
            }
        }
        if ($this->adminId != 1){
            $list_where[] = ['admin_id', '=', $this->adminId];
            $list_where[] = ['area_id', 'in', $this->adminData['area_ids']];
        }
        // 获取长时间订单未结束订单
        if ($is_overtime == 1){
            $end_time = NEW_TIME - (3600 * 24 * 1);
            $list_where[] = ['start_time', 'egt', $end_time];
        }
        // 是否只查询官方账号
        if (!empty($is_account)){
            $list_where[] = ['is_account', '=', 1];
        }
        $list_where[] = ['status', 'in', '1,2,3,4'];
        if (!empty($status)){
            $list_where[] = ['status', '=', $status];
        }
        // 远程今日还车统计
        $order_model = new \app\common\model\Order();
        $data = $order_model->getLists($list_where, 10, 'start_time desc,order_id desc', 'order_id');

        View::assign([
            'status'=>$status,
            'keywords'=>$keywords,
            'time_range'=>$time_range,
            'start_time'=>$start_time,
            'end_time'=>$end_time,
            'is_account'=>$is_account,
            'count'=>$data['count'],
            'list'=>$data['list'],
            'page'=>$data['page']
        ]);
        return View::fetch();
    }

    public function journey()
    {
        $order_id = input('param.order_id', 0, 'intval');
        if (empty($order_id)){
            $this->returnError('fail to load');
        }
        $order_model = new \app\common\model\Order();
        $order_filed = 'order_id,vehicle_id,start_time,end_time,start_gps,end_gps,gps,area_id,status';
        $data = $order_model->getFind($order_id, $order_filed);
        if (empty($data)){
            $this->returnError('fail to load');
        }
        $area_id = $data['area_id'];
        if ($data['status'] > 2){
            $gps_data = json_decode($data['gps'], true);
        }else{
            $vehicle_model = new \app\common\model\Vehicle();
            $gps_data = $vehicle_model->getVehicleGps($data['vehicle_id'], $data['start_time']);
            if (empty($gps_data)){
                $this->returnError('fail to load');
            }
        }
        $center = [];
        $end_gps = [];
        $new_data = [];
        foreach ($gps_data as $key=>$val){
            $gd_gps = bd_decrypt($val['lng'], $val['lat']);
            if ($key == count($gps_data) - 1){
                $center['lng'] = $gd_gps['lng'];
                $center['lat'] = $gd_gps['lat'];
            }
            if ($key == 0){
                $end_gps['lng'] = $gd_gps['lng'];
                $end_gps['lat'] = $gd_gps['lat'];
            }
            $new_data[] = [$gd_gps['lng'], $gd_gps['lat']];
        }
        // 获取网点信息
        $fixed_where = [];
        if ($this->adminData['role_id'] != 1){
            $fixed_where['admin_id'] = $this->adminId;
        }
        if (!empty($area_id)){
            $fixed_where['area_id'] = $area_id;
        }
        if (!empty($end_gps['lng']) && !empty($end_gps['lat'])){
            $around = squarePoint($end_gps['lng'], $end_gps['lat']);
            $fixed_where['glat'] = [['egt',$around['right-bottom']['lat']],['elt',$around['left-top']['lat']],'and'];
            $fixed_where['glng'] = [['egt',$around['left-top']['lng']],['elt',$around['right-bottom']['lng']],'and'];
        }
        $fixed_where['state'] = 1;
        // 获取区域信息
        $area_model = new \app\common\model\Area();
        $fixed_path = $area_model->getField($area_id, 'fixed_path');
        $area_list = $area_model->fixedPath($fixed_path, 0, false);

        View::assign([
            'gps'=>json_encode($new_data),
            'center'=>$center,
            'area_list'=>json_encode($area_list)
        ]);
        return View::fetch('journey');
    }

    // 远程锁车
    public function remoteLock()
    {
        if (request()->isPost())
        {
            $order_id = input('param.order_id',0,'intval');
            $forced = input('param.forced',0,'intval');
            $extra_price = input('param.extra_price',0,'intval');
            $remark = input('param.remark');
            if (empty($order_id)){
                $this->jsonReturn(0,'','操作失败');
            }
            // 获取车辆信息
            $order_model = new \app\common\model\Order();
            $order_data = $order_model->getFind($order_id);
            if (empty($order_data)){
                $this->jsonReturn(0,'','操作失败');
            }
            $vehicle_model = new \app\common\model\Vehicle();
            $vehicle_fields = 'vehicle_id,device,password,blue_tooth_type,token,last_time,fixed_id,';
            $vehicle_fields .= 'lng,lat,blng,blat,glat,glng,mileage,order_number';
            $vehicle_data = $vehicle_model->getFind($order_data['vehicle_id'], $vehicle_fields);
            // Get token information
            $token = $vehicle_model->getToken($vehicle_data['blue_tooth_type']);
            if ($vehicle_data['blue_tooth_type'] == 1){
                import('ego.TbtGps');
                $ego = new \TbtGps();
            }else{
                import('ego.DrGps');
                $ego = new \DrGps();
            }
            if ($order_data['status'] < 3){
                // Acquire vehicle location
                $last_gps = $ego->last_gps($vehicle_data['device'], $token);
                if (!empty($last_gps)){
                    $gd_gps = [
                        'lat'=>$last_gps['glat'],
                        'lng'=>$last_gps['glng']
                    ];
                    $bd_gps = [
                        'lat'=>$last_gps['blat'],
                        'lng'=>$last_gps['blng']
                    ];
                }else{
                    $gd_gps = [
                        'lat'=>$vehicle_data['glat'],
                        'lng'=>$vehicle_data['glng']
                    ];
                    $bd_gps = [
                        'lat'=>$vehicle_data['blat'],
                        'lng'=>$vehicle_data['blng']
                    ];
                }
                // 发送锁车指令
                if ($order_data['status'] == 1) {
                    if (!$ego->stop($vehicle_data['device'], $token)){
                        if ($forced == 0){
                            $this->jsonReturn(0,'','远程还车,请稍后重试');
                        }
                    }
                }
                // 保存车辆GPS信息
                $gps = $vehicle_model->getVehicleGps($vehicle_data['vehicle_id'], $order_data['start_time']);
                // 行驶距离
                $run_distance = 0;
                if (!empty($gps)){
                    if (is_array($gps)){
                        foreach ($gps as $key=>$val){
                            if ($key < count($gps)-1){
                                $next_gps = [
                                    'lng'=>$gps[$key+1]['lng'],
                                    'lat'=>$gps[$key+1]['lat']
                                ];
                                if (!empty($val['lng']) && !empty($val['lat']) && !empty($next_gps['lng']) && !empty($next_gps['lat'])){
                                    $run_distance += getDistance($val['lng'],$val['lat'],$next_gps['lng'],$next_gps['lat'],1);
                                }
                            }
                        }
                    }
                }
                // 行驶距离
                $distance = round($run_distance / 1000, 2);
                // 累计行驶多少公里
                $mileage = floatval($vehicle_data['mileage']) +  floatval($distance);
                // 累计行驶订单数量
                $order_number = intval($vehicle_data['order_number']) + 1;
                $update_data = [
                    'lng'=>$bd_gps['lng'],
                    'lat'=>$bd_gps['lat'],
                    'glng'=>$gd_gps['lng'],
                    'glat'=>$gd_gps['lat'],
                    'blng'=>$bd_gps['lng'],
                    'blat'=>$bd_gps['lat'],
                    'mileage'=>$mileage,
                    'order_number'=>$order_number,
                    'last_time'=>NEW_TIME,
                    'vehicle_id'=>$vehicle_data['vehicle_id'],
                    'is_network'=>0,
                    'red_packet'=>0,
                    'status'=>0,
                ];
                // 更新车辆信息
                $end_gps = $gd_gps['lng'] . ',' . $gd_gps['lat'];
                $end_path = $vehicle_model->getPath($end_gps);
                $update_data['city_path'] = $end_path;
                $vehicle_model->operation($update_data, false);
                // 计算行使时间
                $curr_time = NEW_TIME - $order_data['start_time'];
                $minute = ceil($curr_time / 60); // 骑行时长（分钟）
                $run_time = $minute;
                // 获取用户今日骑行时间
                $day_time = 0;
                $curr_day = date('Y-m-d', $order_data['start_time']);
                $start_time = strtotime($curr_day . ' 00:00:00');
                $end_time = strtotime($curr_day . ' 23:59:59');
                $day_where['member_id'] = $order_data['member_id'];
                $day_where['vehicle_id'] = $order_data['vehicle_id'];
                $day_where['end_time'] = [['egt', $start_time], ['elt', $end_time]];
                $day_where['status'] = 4;
                $day_list = $order_model->getList($day_where, '', '', 'order_id,end_time,start_time');
                if (!empty($day_list)){
                    if (is_array($day_list)){
                        foreach ($day_list as $key=>$val){
                            $day_time += ($val['end_time'] - $val['start_time']);
                        }
                    }
                }
                if ($day_time > 0){
                    $day_time = intval($day_time/60);
                }
                $is_network = 0;
                $is_outside = 0;
                if ($extra_price == 1){
                    $is_outside = 1;
                }
                if ($extra_price == 2){
                    $is_network = 1;
                }
                // 订单计费
                $price_data = $order_model->orderPrice(
                    $order_data['type_id'], $order_data['area_id'],
                    $day_time, $run_time, $distance, $is_network, $is_outside
                );
                // 官方账户免费骑行
                if ($order_data['is_account'] == 1){
                    $price_data = [
                        'total'=>$price_data['total'],
                        'money'=>0,
                        'extra_price'=>0,
                        'time_price'=>0,
                        'distance_price'=>0
                    ];
                }
                // 保存订单信息
                $save_data = [
                    'order_id'=>$order_data['order_id'],
                    'status'=>3, // 3未付款，4已付款
                    'remark'=>$remark,
                    'duration'=>$minute,
                    'distance'=>$distance,
                    'gps'=>json_encode($gps),
                    'total'=>$price_data['total'],
                    'money'=>$price_data['money'],
                    'extra_price'=>$price_data['extra_price'],
                    'time_price'=>$price_data['time_price'],
                    'distance_price'=>$price_data['distance_price'],
                    'end_gps'=>$end_gps,
                    'end_path'=>$end_path,
                    'end_time'=>NEW_TIME,
                    'is_network'=>$is_network,
                    'is_area'=>$is_outside,
                ];
                $order_model->operation($save_data, false);
                // 用车后退款时间往后顺延
                $finance_where['type'] = ['in', '9,32'];
                $finance_where['is_payment'] = 1;
                $finance_where['state'] = 0;
                $finance_where['member_id'] = $order_data['member_id'];
                $member_finance = new MemberFinance();
                $finance_id = $member_finance->getField($finance_where, 'finance_id');
                if (!empty($finance_id)){
                    $member_finance->where('finance_id', $finance_id)->update(['update_time'=>NEW_TIME + (3600 * 24)]);
                }
                // Push order message
                $member_model = new \app\common\model\Member();
                $push_alias = $member_model->getField($order_data['member_id'], 'alias');
                // 小程序端不发送推送
                if (!empty($push_alias)){
                    // Push content
                    $alert = '行程已结束，请及时付款';
                    $extras = [
                        'type'=>'order',
                        'contents'=>'您的行程已结束，请及时付款',
                        'ids'=>$order_data['order_id']
                    ];
                    $setting_model = new \app\common\model\Setting();
                    $setting_model->ruleExec($alert, $push_alias, $extras);
                }
                $this->jsonReturn(1,'','操作成功');
            }
            $this->jsonReturn(0,'','操作失败');
        }
        $this->jsonReturn(0,'','操作失败');
    }

    // 确认付款
    public function confirmLock()
    {
        $order_id = input('param.order_id',0,'intval');
        if (empty($order_id)){
            $this->returnError('操作失败');
        }
        // 获取订单信息
        $order_model = new \app\common\model\Order();
        $order_model->fields = 'order_id,total,member_id,vehicle_id,status';
        $order_data = $order_model->getFind($order_id);
        if (empty($order_data)){
            $this->returnError('操作失败');
        }
        if ($order_data['status'] != 3){
            $this->returnError('操作失败');
        }
        $save_data = [
            'order_id'=>$order_data['order_id'],
            'total'=>$order_data['total'],
            'money'=>0,
            'extra_price'=>0,
            'time_price'=>0,
            'distance_price'=>0,
            'payment_time'=>NEW_TIME,
            'payment_mode'=>1,
            'platform_pay'=>1,
            'status'=>4
        ];
        $order_model->save($save_data);
        // Push order message
        $member_model = new \app\common\model\Member();
        $push_alias = $member_model->getField($order_data['member_id'], 'alias');
        // 小程序端不发送推送
        if (!empty($member_token)){
            // Push content
            $alert = '订单已付款';
            $extras = [
                'type'=>'paymentSuccess',
                'contents'=>'订单已付款，欢迎下次使用',
                'ids'=>$order_data['order_id']
            ];
            $setting_model = new \app\common\model\Setting();
            $setting_model->ruleExec($alert, $push_alias, $extras);
        }
        $this->returnSuccess('操作成功');
    }

    // 订单退款
    public function orderRefund()
    {
        $order_id = input('param.order_id',0,'intval');
        if (empty($order_id)){
            $this->redirect('Order/index');
        }
        // 获取车辆信息
        $order_model = new \app\common\model\Order();
        if (request()->isPost())
        {
            $data = input('post.');
            if ($data['money'] == ''){
                $this->returnError('请输入退款金额');
            }
            $data['money'] = floatval($data['money']);
            $admin_model = new \app\common\model\Admin();
            $password = $admin_model->getField($this->adminId, 'password');
            if (!empty($password)){
                if (empty($data['password'])){
                    $this->returnError('请输入账户密码');
                }
                if ($password != md5($data['password'])){
                    $this->returnError('账户密码有误');
                }
                unset($data['password']);
            }
            // 获取订单金额信息
            $order_fields = 'order_id,order_code,member_id,total,discount,money,refund_money';
            $result = $order_model->getFind($data['order_id'], $order_fields);
            if (empty($result)){
                $this->returnError('退款失败1');
            }
            if ($data['money'] > $result['money']){
                $this->returnError('退款金额不能大于订单金额');
            }
            // 获取支付信息
            $finance_where['ids'] = $result['order_id'];
            $finance_where['type'] = 3;
            $finance_where['is_payment'] = 1;
            $member_finance = new MemberFinance();
            $member_finance->fields = 'finance_id,order_code,type_id,vehicle_id,area_id,fixed_id,admin_id,payment_mode,money';
            $finance_data = $member_finance->getFind($finance_where);
            if (empty($finance_data)){
                $order_model->where('order_id', $data['order_id'])->update(['money'=>$result['money'], 'refund_money'=>$result['refund_money']]);
                $this->returnError('退款失败2');
            }
            // 记录退款金额
            $money = floatval($data['money']);
            // 累计退款金额
            $refund_money = floatval($result['refund_money']) + $money;
            // 剩余金额
            $remaining_amount = floatval($result['total']) - floatval($result['discount']) - $refund_money;
            $rows = $order_model->where('order_id', $data['order_id'])->update(['money'=>$remaining_amount, 'refund_money'=>$refund_money]);
            if (empty($rows)){
                $this->returnError('退款失败3');
            }
            // 保存订单退款记录
            $body = '订单退款';
            $order_code = order_code();
            if (!empty($money)){
                $save_data = [
                    'remark'=>$body,
                    'order_code'=>$order_code,
                    'trade_code'=>$finance_data['order_code'], // 订单交易号
                    'total'=>floatval($finance_data['money']),
                    'money'=>$money,
                    'member_id'=>$result['member_id'],
                    'type_id'=>$finance_data['type_id'],
                    'vehicle_id'=>$finance_data['vehicle_id'],
                    'area_id'=>$finance_data['area_id'],
                    'fixed_id'=>$finance_data['fixed_id'],
                    'admin_id'=>$finance_data['admin_id'],
                    'payment_mode'=>$finance_data['payment_mode'],
                    'type'=>6,
                    'ids'=>$result['order_id'],
                    'create_time'=>NEW_TIME
                ];
                $finance_id = $member_finance->insert($save_data, false);
                if (empty($finance_id)){
                    $order_model->where('order_id', $data['order_id'])->update(['money'=>$result['money'], 'refund_money'=>$result['refund_money']]);
                    $this->returnError('退款失败4');
                }
                // 微信退款
                if ($finance_data['payment_mode'] == 2 || $finance_data['payment_mode'] == 5){
                    $we_chat_pay = new WeChatPay();
                    if (!$we_chat_pay->refund($order_code, $finance_data['order_code'], floatval($finance_data['money']), $money,'订单退款')){
                        $order_model->where('order_id', $data['order_id'])->update(['money'=>$result['money'], 'refund_money'=>$result['refund_money']]);
                        $this->returnError('退款失败5');
                    }
                    $member_finance->refundSuccess($save_data);
                }
                // 支付宝退款
                if ($finance_data['payment_mode'] == 3 || $finance_data['payment_mode'] == 6){
                    $ali_pay = new AliPay();
                    if (!$ali_pay->refund($order_code, $result['order_code'], $money, '订单退款')){
                        $order_model->where('order_id', $data['order_id'])->update(['money'=>$result['money'], 'refund_money'=>$result['refund_money']]);
                        $this->returnError('退款失败6');
                    }
                    $member_finance->refundSuccess($save_data);
                }
                // 余额退款
                if ($finance_data['payment_mode'] == 1){
                    // 增加用户账户金额
                    $member_balance = new MemberBalance();
                    $rows = $member_balance->balanceInc($result['member_id'], $refund_money);
                    if (!$rows){
                        $order_model->where('order_id', $data['order_id'])->update(['money'=>$result['money'], 'refund_money'=>$result['refund_money']]);
                        $this->returnError('退款失败7');
                    }
                    $member_finance->refundSuccess($save_data);
                }
                $member_finance->where('finance_id', $finance_id)->update(['update_time'=>NEW_TIME,'is_payment'=>1,'state'=>1]);
            }
            $this->returnSuccess('退款成功', url('Order/index', ['p'=>$this->p]), true);
        }
        $order_model->fields = 'order_id,order_code,mobile,time_price,extra_price,money,refund_money,member_id,status';
        $order_data = $order_model->getFind($order_id);
        if (empty($order_data)){
            $this->redirect('Order/index');
        }
        $member_model = new \app\common\model\Member();
        $member_data = $member_model->getFind($order_data['member_id'], 'member_id,email,nickname');
        $order_data['email'] = $member_data['email'];
        $order_data['nickname'] = $member_data['nickname'];
        View::assign([
            'order_data'=>$order_data,
        ]);
        return View::fetch();
    }

}